/**
 * @format
 * @Author: TC
 * @Date: 2023-02-17 11:00:25
 * @LastEditTime: 2023-02-22 12:18:16
 * @Description:
 */

import { app } from "../App";
import { IBaseInterface } from "../Interface/BaseInterface";
import { SingleBase } from "../Interface/SingleBase";
import { IEventInstance } from "../Module/Event/EventInterface";
import { EventUnit } from "../Module/Event/EventUnit";

/**
 * 事件管理
 */
export class EventManager implements IBaseInterface {
    private _mapEvent: Map<string | number, EventUnit> = new Map();

    public init(): void {}

    /**
     * 注册事件
     * @param key 事件名
     * @param callback 回调函数
     * @param thisObj this对象
     */
    public register(key: string | number, callback: Function, thisObj: any) {
        let eventUnit = this._mapEvent.get(key);
        const iEvent: IEventInstance = {
            callback: callback,
            thisObj: thisObj,
        };
        if (!eventUnit) {
            eventUnit = new EventUnit(iEvent);
            this._mapEvent.set(key, eventUnit);
        } else {
            eventUnit.addListener(iEvent);
        }
    }

    /**
     * 移除事件
     * @param key 事件名
     */
    public unregister(key: string, thisObj: any) {
        if (this._mapEvent.has(key)) {
            this._mapEvent.get(key).removeListenerByTarget(thisObj);
        } else {
            app.log.error("unregister event not found: - " + key);
        }
    }

    /**
     * 派发事件
     * @param key 事件名
     * @param arg 参数
     */
    public dispatch(key: string | number, arg?: any) {
        const eventUnit = this._mapEvent.get(key);
        if (eventUnit) {
            eventUnit.execute(arg);
        } else {
            app.log.warn("dispatch event not found: - " + key);
        }
    }

    /**
     * 注销某个对象上注册的事件
     * @param thisObg
     */
    unregisterByTarget(thisObg: any): void {
        this._mapEvent.forEach((evt) => {
            evt.listEvent.forEach((iEvt) => {
                if (iEvt.thisObj === thisObg) {
                    evt.removeListenerByTarget(thisObg);
                }
            });
        });
    }

    public release() {
        this._mapEvent.forEach((e) => {
            e.release();
        });
        this._mapEvent.clear();
        this._mapEvent = null;
    }
}
